<?php
require_once 'models/order.inc';
require_once 'models/TMSACL.inc';
require_once 'util/delivery.inc';

class TMSOrderItem extends TCandyItem {
	public function DeliveryCost(){
		return $this->Model->DeliveryCost($this->Base);
	}
	
	public function TotalCost(){
		return $this->Amount + $this->DeliveryCost();
	}
	
	public function __toString(){
		return $this->Id.' ['.$this->Added.'] '.$this->Customer.' : '.$this->Amount.' '.$this->Model->Application()->CurrencyShortName.'/'.$this->Quantaty;
	}	
}

class TMSOrderModel extends TCandyModel {
/**
 * @var TMSACL
 */	
	protected $_ioc_acl_;
	
/**
 * @var TCatalogProductModel
 */	
	protected $_ioc_product_model_;
	
/**
 * @var TMSDeliveryModel
 */	
	protected $_ioc_delivery_model_;
	
	protected $_state_names_ = array(
		TMSOrderState::INBOX => 'Inbox',
		TMSOrderState::INWORK => 'In process',
		TMSOrderState::PAID => 'Paid',
		TMSOrderState::CANCELED => 'Canceled'
	);
	
	protected function afterConstruct(){
		$this->_conf_classname_ = 'TMSOrder';
	}
	
	public function __set($nm,$value){
		switch ($nm){
			case 'StateNames':{
				if (is_string($value))
					$value = json_decode($value,true);
				if (is_array($value)){
					foreach ($value as $key=>$text){
						$state = new TMSOrderState(is_numeric($key)?$key:(defined('TMSOrderState::'.strtoupper($key))?constant('TMSOrderState::'.strtoupper($key)):$key)); 
						$this->_state_names_[(int)$state->__toString()] = $value;
					}
				}
			}break;
			case 'DeliveryModel':{
				parent::__set($nm,$value);
				$this->Wrapper = $value;
			}break;
			default:parent::__set($nm,$value);break;
		}
	}
	
	public function DeliveryCost(TMSOrder $order){
		if ($order->Delivery){
			$com = $this->Instance($order->Delivery->Code);
			if (!($com instanceof IDeliveryProvider))
				$com = $this->Application()->Instantiate($order->Delivery->Component, array('name'=>$order->Delivery->Code,'container'=>$this->container));			
			
			foreach ($order->Delivery->SetupData as $nm=>$data)
				$com->$nm = $data->value;
			
			return $com->DeliveryCostByOrder($order);	
		}
		return 0;
	} 
	
	public function CheckItemProperty(TNOrmObject $object, TOrmPropertyMeta $property){
		if (!is_null($object->State) && $object->State != TMSOrderState::INWORK)
			if ($property->Name() != 'State')
				$property->ReadOnly = true;
		if (($property->Name() == 'GuestName') || ($property->Name() == 'GuestPhone') || ($property->Name() == 'GuestEmail') || ($property->Name() == 'GuestAddress'))
			if ($object->Client)
				return false;
		if ($property->Name() == 'Client')
			if ($object->GuestEmail || $object->GuestPhone)
				return false;
		if ($property->Name() == 'State'){
			$selection = array();
			switch ($object->State){
				case TMSOrderState::INBOX:$selection = array(
												TMSOrderState::INBOX => $this->_state_names_[TMSOrderState::INBOX],
												TMSOrderState::INWORK => $this->_state_names_[TMSOrderState::INWORK]
											);break;
				case TMSOrderState::INWORK:$selection = array(
												TMSOrderState::INWORK => $this->_state_names_[TMSOrderState::INWORK],
												TMSOrderState::PAID => $this->_state_names_[TMSOrderState::PAID],
												TMSOrderState::CANCELED => $this->_state_names_[TMSOrderState::CANCELED]
											);break;
				case TMSOrderState::PAID:$selection = array(
												TMSOrderState::PAID => $this->_state_names_[TMSOrderState::PAID]
											);break;
				case TMSOrderState::CANCELED:$selection = array(
												TMSOrderState::CANCELED => $this->_state_names_[TMSOrderState::CANCELED]
											);break;
			}
			$property->SetSelection($selection);
		}				
		return true;
	}
	
	protected function postProcessProperties(){
		parent::postProcessProperties();
		$this->propertyMetas['Customer'] = new TOrmPropertyMeta('Customer', 'Customer', TItemPropertyType::PT_STRING);
		$this->propertyMetas['Customer']->ReadOnly = true;
		$this->propertyMetas['Comment']->Type = TItemPropertyType::PT_MULTILINE;
		$this->propertyMetas['GuestAddress']->Type = TItemPropertyType::PT_MULTILINE;
		$this->propertyMetas['Amount'] = new TOrmPropertyMeta('Amount', 'Amount', TItemPropertyType::PT_DEC);
		$this->propertyMetas['Amount']->ReadOnly = true;
		$this->propertyMetas['Client']->ReadOnly = true;
		$this->propertyMetas['Positions']->ReadOnly = false;
		$this->propertyMetas['Executor']->ReadOnly = true;
		$this->propertyMetas['Added']->ReadOnly = true;
		$selection = array();
		$dm = $this->DeliveryModel->GetList();
		foreach ($dm as $m)
			$selection[$m->Code] = (string)$m;
		$this->propertyMetas['Delivery']->SetSelection($selection);
	}
	
	protected function beforeSave(TNOrmObject $object){
		$object = parent::beforeSave($object);
		$u = $this->Acl->CurrentUser();
		if ($object->State > TMSOrderState::INBOX && !$object->Executor){
			if (!($u instanceof TMSUser))
				throw new TCoreException(TCoreException::ERR_ACCESS_DENIED);
			$object->Executor = $u;
		}
		
		if (!$object->Id){
			if ($u instanceof TMSClient){
				if ($u->Roles && TMSRole::CLIENT)
					$object->Client = $u->Id;
				else
					throw new TCoreException(TCoreException::ERR_ACCESS_DENIED);	
			}
			if (!$object->Added)
				$object->Added = new TDate();
			if (!$object->State)
				$object->State = new TMSOrderState(TMSOrderState::INBOX);
		} else if ($object->State > TMSOrderState::INWORK){
			$old = $this->Adapter->Load($this->getDummy($object->Id));
			if ($old->State == TMSOrderState::INWORK){
				foreach ($object->Positions as $pos){
					switch ($object->State) { 
						case TMSOrderState::PAID:{
							$this->ProductModel->EditItem($pos->Product->Id, array(
								'Quantaty'=>($pos->Product->Quantaty > $pos->Quantaty)?($pos->Product->Quantaty - $pos->Quantaty):0,
								'Reserved'=>($pos->Product->Reserved > $pos->Quantaty)?($pos->Product->Reserved - $pos->Quantaty):0
							));
						}break;
						case TMSOrderState::CANCELED:
							$this->ProductModel->EditItem($pos->Product->Id, array('Reserved'=>($pos->Product->Reserved > $pos->Quantaty)?($pos->Product->Reserved - $pos->Quantaty):0));
						break;
					}
				}
			}	
		}
		return $object;
	}
	
	public function WrapObject($object, array &$caller_stack = array()){
		if ($object instanceof $this->_conf_classname_)
			return new TMSOrderItem($object,$this);
		return parent::WrapObject($object,$caller_stack);
	}	
}